package com.gitee.sop.gateway.config;

import com.gitee.sop.gateway.service.ParamExecutor;
import com.gitee.sop.gateway.service.RouteService;
import com.gitee.sop.gateway.service.Serde;
import com.gitee.sop.gateway.service.impl.ParamExecutorImpl;
import com.gitee.sop.gateway.service.impl.RouteServiceImpl;
import com.gitee.sop.gateway.service.impl.SerdeGsonImpl;
import com.gitee.sop.gateway.service.impl.SerdeImpl;
import com.gitee.sop.gateway.service.manager.ApiManager;
import com.gitee.sop.gateway.service.manager.IsvApiPermissionManager;
import com.gitee.sop.gateway.service.manager.IsvManager;
import com.gitee.sop.gateway.service.manager.SecretManager;
import com.gitee.sop.gateway.service.manager.impl.LocalApiManagerImpl;
import com.gitee.sop.gateway.service.manager.impl.LocalIsvApiPermissionManagerImpl;
import com.gitee.sop.gateway.service.manager.impl.LocalIsvManagerImpl;
import com.gitee.sop.gateway.service.manager.impl.LocalSecretManagerImpl;
import com.gitee.sop.gateway.service.manager.impl.RedisApiManagerImpl;
import com.gitee.sop.gateway.service.manager.impl.RedisIsvApiPermissionManagerImpl;
import com.gitee.sop.gateway.service.manager.impl.RedisIsvManagerImpl;
import com.gitee.sop.gateway.service.manager.impl.RedisSecretManager;
import com.gitee.sop.support.message.OpenMessageFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * @author 六如
 */
@Configuration
@Slf4j
public class GatewayConfig {

    @Bean
    @ConditionalOnProperty(value = "gateway.manager.api", havingValue = "local", matchIfMissing = true)
    public ApiManager localApiManager() {
        return new LocalApiManagerImpl();
    }

    @Bean
    @ConditionalOnProperty(value = "gateway.manager.api", havingValue = "redis")
    public ApiManager redisApiManager() {
        return new RedisApiManagerImpl();
    }

    @Bean
    @ConditionalOnProperty(value = "gateway.manager.isv", havingValue = "local", matchIfMissing = true)
    public IsvManager localIsvManager() {
        return new LocalIsvManagerImpl();
    }

    @Bean
    @ConditionalOnProperty(value = "gateway.manager.isv", havingValue = "redis")
    public IsvManager redisIsvManager() {
        return new RedisIsvManagerImpl();
    }

    @Bean
    @ConditionalOnProperty(value = "gateway.manager.secret", havingValue = "local", matchIfMissing = true)
    public SecretManager localSecretManager() {
        return new LocalSecretManagerImpl();
    }

    @Bean
    @ConditionalOnProperty(value = "gateway.manager.secret", havingValue = "redis")
    public SecretManager redisSecretManager() {
        return new RedisSecretManager();
    }

    @Bean
    @ConditionalOnProperty(value = "gateway.manager.isv-api-perm", havingValue = "local", matchIfMissing = true)
    public IsvApiPermissionManager localIsvApiPermissionManager() {
        return new LocalIsvApiPermissionManagerImpl();
    }

    @Bean
    @ConditionalOnProperty(value = "gateway.manager.isv-api-perm", havingValue = "redis")
    public IsvApiPermissionManager redisIsvApiPermissionManager() {
        return new RedisIsvApiPermissionManagerImpl();
    }

    // 默认使用fastjson2序列化
    @Bean
    @ConditionalOnProperty(value = "gateway.serialize.json-formatter", havingValue = "fastjson2", matchIfMissing = true)
    public Serde serdeFastjson2() {
        log.info("[init]使用fastjson2序列化");
        return new SerdeImpl();
    }

    @Bean
    @ConditionalOnProperty(value = "gateway.serialize.json-formatter", havingValue = "gson")
    public Serde serdeGson() {
        log.info("[init]使用gson序列化");
        return new SerdeGsonImpl();
    }

    @Bean
    @ConditionalOnMissingBean
    public ParamExecutor paramExecutor() {
        return new ParamExecutorImpl();
    }

    @Bean
    @ConditionalOnMissingBean
    public RouteService routeService() {
        return new RouteServiceImpl();
    }

    @Bean
    @ConditionalOnMissingBean
    public Serde serde() {
        return new SerdeImpl();
    }

    @PostConstruct
    public void init() {
        OpenMessageFactory.initMessage();
    }
}
